import React from 'react';
import { Modal, Tabs, Tree, Button, Icon, Empty, Avatar, Input } from 'antd';
import cn from 'classnames';
// import _ from 'lodash';
// import xss from 'xss';
import { employeeList, companyGettree } from '@/services/Organization/staffmanage';
import styles from './EmployeeSelectModal.less';

const { TabPane } = Tabs;
const { TreeNode } = Tree;
const { Search } = Input;

const TYPE = {
    EMPLOYEE: '1',
    DEPARTMENT: '2',
    JOB: '3',
    RANK: '4'
};
const EMPLOYEE = {
    RECENT: '1',
    ALL: '2',
    DEPARTMENT: '3',
    JOB: '4',
    RANK: '5'
};

const getKey = ({ companyId = '', departmentId = '', id = '', userCode }) => {
    if (userCode) {
        return `${companyId}-${departmentId}-${id}`;
    }
    return `${companyId}-${id === companyId ? '' : id}`;
};

const tabList = [
    {
        title: '选人员',
        key: TYPE.EMPLOYEE
    },
    {
        title: '选部门',
        key: TYPE.DEPARTMENT
    },
    {
        title: '选职位',
        key: TYPE.JOB,
        disable: true
    },
    {
        title: '选职级',
        key: TYPE.RANK,
        disable: true
    }
];

const childTabList = [
    {
        title: '最近',
        key: EMPLOYEE.RECENT
    },
    {
        title: '所有人员',
        key: EMPLOYEE.ALL
    },
    {
        title: '按部门',
        key: EMPLOYEE.DEPARTMENT
    },
    {
        title: '按职位',
        key: EMPLOYEE.JOB,
        disable: true
    },
    {
        title: '按职级',
        key: EMPLOYEE.RANK,
        disable: true
    }
];

const EmployeeSelectModal = ({ value, maxCount, disableArr, visible, setVisible, onOk }) => {
    // const [visible, setVisible] = React.useState(false);
    const [activeKey, setActiveKey] = React.useState('1');
    const [childActiveKey, setChildActiveKey] = React.useState('1');
    const [finalDataSource, setFinalDataSource] = React.useState([]);
    // console.log('EmployeeSelect -> finalDataSource', finalDataSource);
    const [companyTree, setCompanyTree] = React.useState([]);
    // console.log('EmployeeSelect -> companyTree', companyTree);
    const [finalTree, setFinalTree] = React.useState([]);
    // console.log('EmployeeSelect -> finalTree', finalTree);
    const [tempEmployeeList, setTempEmployeeList] = React.useState([]);
    // console.log('EmployeeSelect -> tempEmployeeList', tempEmployeeList);
    const [employeeObj, setEmployeeObj] = React.useState(null);
    // console.log('EmployeeSelect -> employeeObj', employeeObj);
    const [targetKeys, setTargetKeys] = React.useState([]);
    const [leftSelectedKeys, setLeftSelectedKeys] = React.useState([]);
    const [rightSelectedKeys, setRightSelectedKeys] = React.useState([]);
    const [expandedKeys, setExpandedKeys] = React.useState([]);
    const [leftInput, setLeftInput] = React.useState('');

    const getKeyTree = (arr = []) =>
        arr.map(({ children, ...props }) => ({
            ...props,
            key: getKey(props),
            children: getKeyTree(children)
        }));

    const getFinalTree = (arr = []) =>
        arr.map(({ children, ...props }) => {
            const tempKey = `${props.companyId}-${props.id === props.companyId ? '' : props.id}`;
            let tempChildren = [];
            if (children.length > 0) {
                tempChildren = getFinalTree(children);
            }
            if (employeeObj && employeeObj[tempKey]) {
                tempChildren = tempChildren.concat(employeeObj[tempKey]);
            }
            return {
                ...props,
                key: getKey(props),
                children: tempChildren
            };
        });

    const getFinalDataSource = () => {
        const tempDataSource = [];
        const obj = {};
        function flatten(list = []) {
            list.forEach(item => {
                tempDataSource.push(item);
                obj[getKey(item)] = item;
                flatten(item.children);
            });
        }
        flatten(getFinalTree(companyTree));
        tempEmployeeList.forEach(item => {
            obj[getKey(item)] = item;
        });
        // setFinalDataSource(tempDataSource.concat(tempEmployeeList));
        setFinalDataSource(obj);
    };

    const getResultList = () => targetKeys.map(item => finalDataSource[item] || null);

    const getCompanyTree = async () => {
        const res = await companyGettree({ permissionUrl: 'office:orgs:employee' });
        // console.log(res);
        const { code, data = [] } = res;
        if (code === 10000) {
            const arr = getKeyTree(data);
            setCompanyTree(arr);
            if (arr && arr.length > 0) {
                setExpandedKeys([arr[0].key]);
            }
        }
    };

    const getEmployeeList = async ({ companyId = 100, departmentId }) => {
        const res = await employeeList({ companyId, departmentId, pageSize: 99999 });
        const {
            code,
            data: { rows = [] }
        } = res;
        if (code === 10000) {
            const tempList = rows.map(item => ({
                ...item,
                key: getKey(item)
            }));
            setTempEmployeeList(tempList);
            const obj = {};
            tempList.forEach(item => {
                const tempKey = `${item.companyId}-${item.departmentId || ''}`;
                if (obj[tempKey]) {
                    obj[tempKey].push(item);
                } else {
                    obj[tempKey] = [item];
                }
            });
            setEmployeeObj(obj);
        }
    };

    const handleOk = () => {
        const result = getResultList();
        if (onOk) {
            onOk(result);
        }
        setVisible(false);
    };

    const handleCancel = () => {
        setVisible(false);
    };

    const handleTabClick = e => {
        if (e !== activeKey) {
            setLeftSelectedKeys([]);
            setLeftInput('');
            // setExpandedKeys([]);
            setExpandedKeys([companyTree[0].key]);
        }
        setActiveKey(e);
    };

    const handleChildTabClick = e => {
        if (e !== childActiveKey) {
            setLeftSelectedKeys([]);
            setLeftInput('');
        }
        setChildActiveKey(e);
    };

    React.useEffect(() => {
        const tree = getFinalTree(companyTree);
        setFinalTree(tree);
        getFinalDataSource();
    }, [companyTree, employeeObj]);

    React.useEffect(() => {
        getCompanyTree();
        getEmployeeList({});
    }, []);

    // React.useEffect(() => {
    //     if (value) {
    //         const keys = value.map(item => item.key);
    //         setTargetKeys(keys);
    //     } else {
    //         setTargetKeys([]);
    //     }
    // }, [value]);

    React.useEffect(() => {
        if (visible) {
            setActiveKey('1');
            setChildActiveKey('1');
            setLeftInput('');
            if (value) {
                const keys = value.map(item => item.key);
                setTargetKeys(keys);
            } else {
                setTargetKeys([]);
            }
        }
    }, [value, visible]);

    const filteredEmployeeList = React.useMemo(
        () =>
            tempEmployeeList.filter(
                temp => !targetKeys.includes(temp.key) && temp.employeeName.indexOf(leftInput) !== -1
            ),
        [leftInput, tempEmployeeList, targetKeys]
    );

    const handleItemClick = (item, direction) => () => {
        if (direction === 'left') {
            if (maxCount && targetKeys.length >= maxCount) {
                return;
            }
            if (leftSelectedKeys.includes(item.key)) {
                // setLeftSelectedKeys([]);
                setLeftSelectedKeys(leftSelectedKeys.filter(a => a !== item.key));
            } else {
                // setLeftSelectedKeys([item.key]);
                setLeftSelectedKeys([...leftSelectedKeys, item.key]);
            }
        } else if (direction === 'right') {
            if (rightSelectedKeys.includes(item.key)) {
                // setRightSelectedKeys([]);
                setRightSelectedKeys(rightSelectedKeys.filter(a => a !== item.key));
            } else {
                // setRightSelectedKeys([item.key]);
                setRightSelectedKeys([...rightSelectedKeys, item.key]);
            }
        }
    };

    const getChildKeys = arr => {
        const tempDataSource = [];
        function flatten2(list = []) {
            list.forEach(item => {
                if (item.userCode) {
                    tempDataSource.push(item.key);
                }
                flatten2(item.children);
            });
        }
        flatten2(arr);
        return tempDataSource;
    };

    const getChildDepartmentKeys = arr => {
        const tempDataSource = [];
        function flatten2(list = []) {
            list.forEach(item => {
                if (!item.userCode) {
                    tempDataSource.push(item.key);
                }
                flatten2(item.children);
            });
        }
        flatten2(arr);
        return tempDataSource;
    };

    const changeTargetKeys = arr => {
        let tempArr2 = [...new Set([...arr])];
        if (maxCount) {
            tempArr2 = tempArr2.slice(0, maxCount);
        }
        setTargetKeys(tempArr2);
        setLeftSelectedKeys([]);
    };

    const handleAddTarget = () => {
        if (leftSelectedKeys.length <= 0) {
            return;
        }
        if (activeKey === TYPE.EMPLOYEE && childActiveKey === EMPLOYEE.DEPARTMENT) {
            let tempKeys = [];
            leftSelectedKeys.forEach(item => {
                const tempItem = finalDataSource[item];
                if (tempItem.userCode) {
                    tempKeys.push(item);
                } else {
                    const tempArr = getChildKeys(tempItem.children || []);
                    tempKeys = [...tempKeys, ...tempArr];
                }
            });
            changeTargetKeys([...targetKeys, ...tempKeys]);
            // const tempItem = finalDataSource[leftSelectedKeys[0]];
            // if (tempItem.userCode) {
            //     changeTargetKeys([...targetKeys, ...leftSelectedKeys]);
            //     return;
            // }
            // const tempArr = getChildKeys(tempItem.children || []);
            // changeTargetKeys([...targetKeys, ...tempArr]);
            return;
        }
        if (activeKey === TYPE.DEPARTMENT) {
            let tempKeys = [];
            leftSelectedKeys.forEach(item => {
                const tempItem = finalDataSource[item];
                const tempArr = getChildDepartmentKeys(tempItem.children || []);
                tempKeys = [...tempKeys, item, ...tempArr];
            });
            changeTargetKeys([...targetKeys, ...tempKeys]);
            // const tempItem = finalDataSource[leftSelectedKeys[0]];
            // const tempArr = getChildDepartmentKeys(tempItem.children || []);
            // changeTargetKeys([...targetKeys, leftSelectedKeys[0], ...tempArr]);
            return;
        }
        changeTargetKeys([...targetKeys, ...leftSelectedKeys]);
    };

    const handleRemoveTarget = () => {
        if (rightSelectedKeys.length > 0) {
            setTargetKeys(targetKeys.filter(item => !rightSelectedKeys.includes(item)));
            setRightSelectedKeys([]);
        }
    };

    const handleRemoveAllTarget = () => {
        setTargetKeys([]);
        setRightSelectedKeys([]);
    };

    const handleAddAllTarget = () => {
        if (activeKey === TYPE.EMPLOYEE && childActiveKey === EMPLOYEE.RECENT) {
            const list = tempEmployeeList.filter(
                temp => !targetKeys.includes(temp.key) && temp.employeeName.indexOf(leftInput) !== -1
            );
            const tempArr = list.map(item => item.key);
            changeTargetKeys([...targetKeys, ...tempArr]);
            return;
        }
        if (activeKey === TYPE.EMPLOYEE && childActiveKey === EMPLOYEE.ALL) {
            const list = tempEmployeeList.filter(
                temp => !targetKeys.includes(temp.key) && temp.employeeName.indexOf(leftInput) !== -1
            );
            const tempArr = list.map(item => item.key);
            changeTargetKeys([...targetKeys, ...tempArr]);
            return;
        }
        if (activeKey === TYPE.EMPLOYEE && childActiveKey === EMPLOYEE.DEPARTMENT) {
            const tempItem = finalTree[0];
            const tempArr = getChildKeys(tempItem.children || []);
            changeTargetKeys([...targetKeys, ...tempArr]);
            return;
        }
        if (activeKey === TYPE.DEPARTMENT) {
            const tempItem = companyTree[0];
            const tempArr = getChildDepartmentKeys(tempItem.children || []);
            changeTargetKeys([...targetKeys, tempItem.key, ...tempArr]);
        }
    };

    const handleSearch = (inputVal, direction) => {
        if (direction === 'left') {
            setLeftInput(inputVal);
        }
    };

    const hasChild = arr => {
        let flag = false;
        function flatten(list = []) {
            try {
                list.forEach(item => {
                    const { employeeName = '', name = '' } = item;
                    if (employeeName && employeeName.indexOf(leftInput) !== -1) {
                        flag = true;
                    }
                    if (name && name.indexOf(leftInput) !== -1) {
                        flag = true;
                    }
                    flatten(item.children);
                });
            } catch (error) {
                console.log(error);
            }
        }
        flatten(arr);
        return flag;
    };

    const itemHasVal = item => {
        const { employeeName = '', name = '' } = item;
        if (employeeName && employeeName.indexOf(leftInput) !== -1) {
            return true;
        }
        if (name && name.indexOf(leftInput) !== -1) {
            return true;
        }
        return false;
    };

    const showSearch = () =>
        activeKey === TYPE.EMPLOYEE && (childActiveKey === EMPLOYEE.RECENT || childActiveKey === EMPLOYEE.ALL);

    const filterTree = tree => tree;
    // .map(({ children, ...props }) => {
    //     if (props.userCode && targetKeys.includes(props.key)) {
    //         return null;
    //     }
    //     if (itemHasVal(props) || hasChild(children)) {
    //         return { children, ...props };
    //     }
    //     return null;
    // });

    const generateTree = (treeNodes = []) =>
        // console.log(treeNodes);
        treeNodes.map(({ children = [], ...props }) => {
            if (props.userCode && targetKeys.includes(props.key)) {
                return null;
            }
            // console.log(props.name || props.employeeName);
            if (itemHasVal(props) || hasChild(children)) {
                return (
                    <TreeNode
                        {...props}
                        // disabled={checkedKeys.includes(props.key)}
                        title={`${props.employeeName || props.name}`}
                        key={getKey(props)}
                        dataRef={props}
                    >
                        {generateTree(children || [])}
                    </TreeNode>
                );
            }
            return null;
        });

    const renderTree = treeNodes => {
        const tempTree = treeNodes.filter(item => item);
        if (tempTree.length <= 0) {
            return (
                <div style={{ flex: 1, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                    <Empty image={Empty.PRESENTED_IMAGE_SIMPLE}></Empty>
                </div>
            );
        }
        return (
            <Tree
                blockNode
                multiple
                expandedKeys={expandedKeys}
                selectedKeys={leftSelectedKeys}
                defaultExpandAll
                disabled={maxCount && targetKeys.length >= maxCount}
                // filterTreeNode={({ props }) => {
                //     if (leftInput) {
                //         const { employeeName = '', name = '' } = props;
                //         if (employeeName && employeeName.indexOf(leftInput) !== -1) {
                //             return true;
                //         }
                //         if (name && name.indexOf(leftInput) !== -1) {
                //             return true;
                //         }
                //     }
                //     return false;
                // }}
                onSelect={(
                    _,
                    {
                        node: {
                            props: { eventKey }
                        }
                    }
                ) => {
                    if (leftSelectedKeys.includes(eventKey)) {
                        setLeftSelectedKeys(leftSelectedKeys.filter(a => a !== eventKey));
                    } else {
                        setLeftSelectedKeys([...leftSelectedKeys, eventKey]);
                    }
                    // setLeftSelectedKeys([eventKey]);
                    // if (expandedKeys.includes(eventKey)) {
                    //     setExpandedKeys(expandedKeys.filter(item => item !== eventKey));
                    // } else {
                    //     setExpandedKeys([...expandedKeys, eventKey]);
                    // }
                    setExpandedKeys([...new Set([...expandedKeys, eventKey])]);
                }}
                onExpand={keys => {
                    setExpandedKeys(keys);
                }}
            >
                {generateTree(tempTree)}
            </Tree>
        );
    };

    const renderList = (arr, direction) => {
        if (arr && arr.length > 0) {
            return arr.map(item => {
                let icon = <i className="icon iconfont iconyuan" style={{ fontSize: 14, color: '#D9D9D9' }} />;
                if (
                    (direction === 'left' && leftSelectedKeys.includes(item.key)) ||
                    (direction === 'right' && rightSelectedKeys.includes(item.key))
                ) {
                    icon = <i className="icon iconfont iconwancheng" style={{ fontSize: 14, color: '#FFA22D' }} />;
                }
                return (
                    <div key={item.key} className={cn(styles.renderItem)} onClick={handleItemClick(item, direction)}>
                        {item.userCode ? (
                            <Avatar icon="user" size="small" style={{ marginRight: 6 }} />
                        ) : (
                            <Icon
                                type="folder-open"
                                theme="filled"
                                style={{ marginRight: 6, marginLeft: 2, fontSize: 20, color: '#FFCF44' }}
                            />
                        )}

                        {/* eslint-disable-next-line react/no-danger */}
                        <div className={styles.renderName}>
                            {item.name || ''}
                            {item.employeeName && <span title={item.employeeName}>{item.employeeName}</span>}
                            {item.departmentName && (
                                <span title={item.departmentName} className={styles.renderNameLast}>
                                    {item.departmentName}
                                </span>
                            )}
                        </div>
                        {icon}
                    </div>
                );
            });
        }
        return (
            <div style={{ flex: 1, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                <Empty image={Empty.PRESENTED_IMAGE_SIMPLE}></Empty>
            </div>
        );
    };

    const hasNotEmployeeInTarget = arr => {
        let flag = false;
        function flatten(list = []) {
            try {
                list.forEach(item => {
                    const { userCode, key } = item;
                    if (userCode && !targetKeys.includes(key)) {
                        flag = true;
                    }
                    flatten(item.children);
                });
            } catch (error) {
                console.log(error);
            }
        }
        flatten(arr);
        return flag;
    };

    const hasNotInTarget = arr => {
        let flag = false;
        function flatten(list = []) {
            try {
                list.forEach(item => {
                    const { key } = item;
                    if (!targetKeys.includes(key)) {
                        flag = true;
                    }
                    flatten(item.children);
                });
            } catch (error) {
                console.log(error);
            }
        }
        flatten(arr);
        return flag;
    };

    const renderAllBtn = () => {
        let disabled = true;
        let type = '';
        if (!(maxCount && targetKeys.length >= maxCount)) {
            if (activeKey === TYPE.EMPLOYEE && childActiveKey === EMPLOYEE.RECENT) {
                if (filteredEmployeeList.length > 0) {
                    type = 'primary';
                    disabled = false;
                }
            } else if (activeKey === TYPE.EMPLOYEE && childActiveKey === EMPLOYEE.ALL) {
                if (filteredEmployeeList.length > 0) {
                    type = 'primary';
                    disabled = false;
                }
            } else if (activeKey === TYPE.EMPLOYEE && childActiveKey === EMPLOYEE.DEPARTMENT) {
                const tree = filterTree(finalTree);
                const flag = hasNotEmployeeInTarget(tree);
                if (flag) {
                    type = 'primary';
                    disabled = false;
                }
            } else if (activeKey === TYPE.DEPARTMENT) {
                const flag = hasNotInTarget(companyTree);
                if (flag) {
                    type = 'primary';
                    disabled = false;
                }
            }
        }
        return (
            <Button disabled={disabled} type={type} onClick={handleAddAllTarget} style={{ marginTop: 24 }}>
                <Icon type="double-right" style={{ fontSize: 12 }} />
            </Button>
        );
    };

    return (
        <Modal
            title="选择人员"
            width={720}
            centered
            wrapClassName={styles.modalContainer}
            keyboard={false}
            maskClosable={false}
            visible={visible}
            onOk={handleOk}
            onCancel={handleCancel}
        >
            <div className={styles.employeeSelectWrap}>
                <Tabs activeKey={activeKey} size="small" animated={false} onTabClick={handleTabClick}>
                    {tabList.map(item => (
                        <TabPane tab={item.title} key={item.key} disabled={disableArr.includes(item.key)}>
                            {activeKey === TYPE.EMPLOYEE && (
                                <Tabs
                                    activeKey={childActiveKey}
                                    className={styles.firstTab}
                                    size="small"
                                    animated={false}
                                    onTabClick={handleChildTabClick}
                                >
                                    {childTabList.map(childItem => (
                                        <TabPane
                                            tab={childItem.title}
                                            key={childItem.key}
                                            disabled={disableArr.includes(`1-${childItem.key}`)}
                                        ></TabPane>
                                    ))}
                                </Tabs>
                            )}
                        </TabPane>
                    ))}
                </Tabs>
                <div className={styles.transferWrap}>
                    <div>
                        {showSearch() && (
                            <div className={styles.transferHead}>
                                <Search
                                    placeholder="请输入搜索内容"
                                    allowClear
                                    value={leftInput}
                                    onChange={e => handleSearch(e.target.value, 'left')}
                                />
                            </div>
                        )}
                        <div
                            className={cn(styles.transferBox, {
                                [styles.disabled]: maxCount && targetKeys.length >= maxCount
                            })}
                        >
                            {/* 选人员   最近 */}
                            {activeKey === TYPE.EMPLOYEE &&
                                childActiveKey === EMPLOYEE.RECENT &&
                                renderList(filteredEmployeeList, 'left')}
                            {/* 选人员   所有人员 */}
                            {activeKey === TYPE.EMPLOYEE &&
                                childActiveKey === EMPLOYEE.ALL &&
                                renderList(filteredEmployeeList, 'left')}
                            {/* 选人员   按部门 */}
                            {activeKey === TYPE.EMPLOYEE &&
                                childActiveKey === EMPLOYEE.DEPARTMENT &&
                                renderTree(filterTree(finalTree) || [])}
                            {/* 选部门 */}
                            {activeKey === TYPE.DEPARTMENT && renderTree(companyTree)}
                        </div>
                    </div>
                    <div className={styles.actionBox}>
                        <Button
                            disabled={leftSelectedKeys.length <= 0}
                            type={leftSelectedKeys.length > 0 ? 'primary' : ''}
                            onClick={handleAddTarget}
                        >
                            <Icon type="right" style={{ fontSize: 12 }} />
                        </Button>
                        <Button
                            disabled={rightSelectedKeys.length <= 0}
                            type={rightSelectedKeys.length > 0 ? 'primary' : ''}
                            onClick={handleRemoveTarget}
                        >
                            <Icon type="left" style={{ fontSize: 12 }} />
                        </Button>
                        {renderAllBtn()}
                        <Button
                            disabled={targetKeys.length <= 0}
                            type={targetKeys.length > 0 ? 'primary' : ''}
                            onClick={handleRemoveAllTarget}
                        >
                            <Icon type="double-left" style={{ fontSize: 12 }} />
                        </Button>
                    </div>
                    <div>
                        <div className={styles.transferHead}>
                            {/* <Search placeholder="请输入搜索内容" onSearch={value => console.log(value)} /> */}
                            {maxCount && (
                                <div className={styles.resultHead}>
                                    选择
                                    <span>
                                        已选：{targetKeys.length}
                                        {maxCount ? `/${maxCount}` : ''}
                                    </span>
                                </div>
                            )}
                        </div>
                        <div className={styles.transferBox}>{renderList(getResultList(), 'right')}</div>
                    </div>
                </div>
            </div>
        </Modal>
    );
};

EmployeeSelectModal.defaultProps = {
    placeholder: '请选择',
    visible: false,
    disableArr: ['3', '4', '1-4', '1-5'],
    setVisible: () => {},
    onOk: () => {}
};

export default EmployeeSelectModal;
